package com.j.lemon.learn.thread.future;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * @Author lijunjun
 * @Date 2019-03-29 14:30
 * @Description 该例子可以应用在出行网站的路线查询等场景，用户输入履行的日期和其他要求，门户网站获取并显示来自多条航线、公司的报价。
 *              在获取不同公司的报价过程中，可能会调用web服务，访问数据库或其他的一些工作，在这种情况下，为了给用户带来更好的体验，
 *              可以显示在指定时间内获取到的信息，对于在规定时间内没有提供相应的服务，网页可以忽略，或者给出一个提示。invokeAll就可以
 *              很好的完成这个工作。
 */
public class CallableTest implements Callable<String> {
    @Override
    public String call() throws Exception {
        Thread.sleep(1000);
        return "haha";
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(8,16,0, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>(1000),
                r -> new Thread(r,"lala"),
                new ThreadPoolExecutor.DiscardPolicy());


//        Future<String> submit = executor.submit(new CallableTest());
//        long start = System.currentTimeMillis();
//        System.out.println("开始get。。。");
//        while(!submit.isDone()){
//            System.out.println("get中。。。");
//        }
//        String s = submit.get();
//        System.out.println("get到数据！");
//        System.out.println("cost" + (System.currentTimeMillis()-start));
//        System.out.println(s);
//        executor.shutdown();

        List<Callable<String>> tasks = new ArrayList<>();
        System.out.println("添加任务：haha");
        tasks.add(new CallableTest());
        System.out.println("添加任务：C1");
        tasks.add(new C1());
        System.out.println("添加任务：C2");
        tasks.add(new C2());
        System.out.println("添加任务：C3");
        tasks.add(new C3());
        System.out.println("任务添加完毕！");
        long s = System.currentTimeMillis();
        List<Future<String>> futures = executor.invokeAll(tasks,2000,TimeUnit.MILLISECONDS);
        long e = System.currentTimeMillis();
        System.out.println("invokeAll 结束,cost:"+(e-s));

        for (Future<String> future : futures){
            if(future.isCancelled()){
                System.out.println(Thread.currentThread().getName()+"未获取到结果");
            }else{
                System.out.println(Thread.currentThread().getName()+"获取到结果："+future.get());
            }
        }
        executor.shutdown();

    }
}

class C1 implements Callable<String> {
    @Override
    public String call() throws Exception {
        Thread.sleep(1998);
        return "c1";
    }
}

class C2 implements Callable<String> {
    @Override
    public String call() throws Exception {
        Thread.sleep(3000);
        return "c2";
    }
}

class C3 implements Callable<String> {
    @Override
    public String call() throws Exception {
        Thread.sleep(4000);
        return "c3";
    }
}
